﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MCHelp;
using MoreEPG.Model;
using Microsoft.MediaCenter.Guide;
using System.Windows.Threading;

namespace MoreEPG.Data
{
    public class MCData
    {
        private MCConnection MCCon;
        private MCProgramInfoCollection _MCPrograms;
        private MCPersonInfoCollection _MCPersons;
        private MCImageInfoCollection _MCImages;
        private MCChannelInfoCollection _MCChannels;

        private string _LastError;

        private Dispatcher _UiDispatcher;
        private Delegate _ProgressDelegate;


        public MCData(Dispatcher UiDispatcher, Delegate ProgressDelegate)
        {
            this._UiDispatcher = UiDispatcher;
            this._ProgressDelegate = ProgressDelegate;

            try
            {
                this.MCCon = new MCConnection();
            }
            catch (Exception ex)
            {
                this._LastError = ex.Message;
            }
        }

        

        public MCProgramInfoCollection MCPrograms
        {
            get
            {
                return this._MCPrograms;
            }
        }

        public MCPersonInfoCollection MCPersons
        {
            get
            {
                return this._MCPersons;
            }
        }

        public MCImageInfoCollection MCImages
        {
            get
            {
                return this._MCImages;
            }
        }

        public MCChannelInfoCollection MCChannels
        {
            get
            {
                if (this._MCChannels == null)
                {
                    this.FillMCChannels();
                }
                return this._MCChannels;
            }

        }

        public bool FillCollections()
        {
            this._MCPrograms = new MCProgramInfoCollection();
            this._MCImages = new MCImageInfoCollection();
            this._MCPersons = new MCPersonInfoCollection();
            if (this.MCCon == null)
            {
                try
                {
                    this.MCCon = new MCConnection();
                }
                catch (Exception ex)
                {
                    this._LastError = ex.Message;
                    return false;
                }
            }
            Programs progs = new Programs(this.MCCon.Store);
            People persons = new People(this.MCCon.Store);
            GuideImages images = new GuideImages(this.MCCon.Store);

            //Programs
            int count = progs.Count();
            int counter = 0;
            this._UiDispatcher.BeginInvoke(this._ProgressDelegate, 0, count, -4);
            System.Collections.IEnumerator enumerator = progs.GetEnumerator();
            while (enumerator.MoveNext())
            {
                Program p = enumerator.Current as Program;
                int percentage;
                string uid = p.GetUIdValue();
                if (string.IsNullOrEmpty(p.Title) || string.IsNullOrEmpty(p.Description) || string.IsNullOrEmpty(uid))
                {
                    percentage = (int)(((decimal)counter / (decimal)count) * 100);
                    this._UiDispatcher.BeginInvoke(this._ProgressDelegate, percentage, count, -5);
                    counter++;
                    continue;
                }
                MCProgramInfo pInfo = new MCProgramInfo(p.Title, p.Description, uid);
                pInfo.FirstScheduleEntry = p.ScheduleEntries.MinTime;
                if (!this._MCPrograms.ContainsKey(pInfo.HashCode))
                {
                    this._MCPrograms.Add(pInfo.HashCode, pInfo);
                }
                percentage = (int)(((decimal)counter / (decimal)count) * 100);
                this._UiDispatcher.BeginInvoke(this._ProgressDelegate, percentage, count, -5);
                counter++;
            }

            // Images
            count = images.Count();
            counter = 0;
            enumerator = images.GetEnumerator();
            while (enumerator.MoveNext())
            {
                Microsoft.MediaCenter.Guide.GuideImage image = enumerator.Current as Microsoft.MediaCenter.Guide.GuideImage;
                int percentage;
                string uid = image.GetUIdValue();
                if (string.IsNullOrEmpty(image.ImageUrl) || string.IsNullOrEmpty(uid))
                {
                    percentage = (int)(((decimal)counter / (decimal)count) * 100);
                    this._UiDispatcher.BeginInvoke(this._ProgressDelegate, percentage, count, -6);
                    counter++;
                    continue;
                }

                MCImageInfo iInfo = new MCImageInfo(image.ImageUrl, uid);
                if (!this._MCImages.ContainsKey(iInfo.HashCode))
                {
                    this._MCImages.Add(iInfo.HashCode, iInfo);
                }

                percentage = (int)(((decimal)counter / (decimal)count) * 100);
                this._UiDispatcher.BeginInvoke(this._ProgressDelegate, percentage, count, -6);
                counter++;
            }

            // persons
            count = persons.Count();
            counter = 0;
            enumerator = persons.GetEnumerator();
            while (enumerator.MoveNext())
            {
                Microsoft.MediaCenter.Guide.Person person = enumerator.Current as Microsoft.MediaCenter.Guide.Person;
                int percentage;
                string uid = person.GetUIdValue();
                if (string.IsNullOrEmpty(person.Name) || string.IsNullOrEmpty(uid))
                {
                    percentage = (int)(((decimal)counter / (decimal)count) * 100);
                    this._UiDispatcher.BeginInvoke(this._ProgressDelegate, percentage, count, -7);
                    counter++;
                    continue;
                }

                MCPersonInfo pInfo = new MCPersonInfo(person.Name, uid);
                if (!this._MCPersons.ContainsKey(pInfo.HashCode))
                {
                    this._MCPersons.Add(pInfo.HashCode, pInfo);
                }

                percentage = (int)(((decimal)counter / (decimal)count) * 100);
                this._UiDispatcher.BeginInvoke(this._ProgressDelegate, percentage, count, -7);
                counter++;
            }
            progs = null;
            persons = null;
            images = null;
            return true;
        }

        private void FillMCChannels()
        {
            if (this._MCChannels == null)
            {
                this._MCChannels = new MCChannelInfoCollection();
            }
            this._MCChannels.Clear();
            if (this.MCCon != null)
            {
                Channel[] channels = new Channels(this.MCCon.Store).Where(s => s.ChannelType == ChannelType.Scanned && s.UserBlockedState < UserBlockedState.Blocked && s.Lineup != null && s.Visibility == ChannelVisibility.Available && s.Service.ServiceType == ServiceType.TV).ToArray();
                for (int i = 0; i < channels.Count(); i++)
                {
                    Channel chan = channels[i];
                    string match = null;
                    if (chan.MatchName.StartsWith("DVBT") || chan.MatchName.StartsWith("DVBS"))
                    {
                        match = chan.MatchName.Split('|')[0];
                    }
                    else
                    {
                        match = chan.CallSign;
                    }


                    MCChannelInfo c = new MCChannelInfo(chan.CallSign, match, false);
                    this._MCChannels.Add(c);
                }
            }
        }

    }
}
